package com.google.code.maven.plugin.http.client.transformer;

import java.io.File;
import java.io.IOException;
import java.util.Map;

import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.springframework.core.io.Resource;
import org.springframework.util.Assert;

/**
 * <h1>transforms the {@link File} source file to the output {@link File} using the provided xsl style sheet</h1>
 * <p>
 * Note: a Transformer implementation should be provided (e.g. saxon, xalan as plugin dependencies)
 * </p>
 * 
 * @author Nadim Benabdenbi
 * @version 1.0
 * @since JDK1.6
 * 
 * @see AbstractTransformer
 * @see File
 */
public class XsltTransformer extends AbstractTransformer<Resource, Resource> {
	
	/**
	 * the xslt output result
	 * 
	 * @parameter
	 */
	private Resource output;
	
	/**
	 * the xsl resource
	 * 
	 * @parameter
	 */
	private Resource xsl;
	
	/**
	 * the xsl properties parameters
	 * 
	 * @parameter
	 */
	private Map<String, String> parameters;
	
	@Override
	protected Resource doTransform(Resource xml) throws Exception {
		Assert.notNull(xml, "xml file could not be null");
		Assert.isTrue(xml.exists(), "xml file not found [" + xml + "]");
		Assert.notNull(output, "output file could not be null");
		Assert.notNull(xsl, "xsl style sheet file could not be null");
		Assert.isTrue(xsl.exists(), "xsl style sheet not found [" + xsl.getURL() + "]");
		if (output.getFile().getParentFile() != null && !output.getFile().getParentFile().exists()) {
			Assert.isTrue(output.getFile().getParentFile().mkdirs(), "failed to make directory tree for [" + output.getFile().getParentFile() + "]");
		}
		log.info("tranforming [" + xml + "] with [" + xsl + "] to [" + output + "]");
		TransformerFactory factory = TransformerFactory.newInstance();
		StreamSource xslSource = new StreamSource(xsl.getFile());
		StreamSource xmlSource = new StreamSource(xml.getFile());
		StreamResult outputTarget = new StreamResult(output.getFile());
		javax.xml.transform.Transformer transformer = factory.newTransformer(xslSource);
		if (parameters != null) {
			for (String key : parameters.keySet()) {
				transformer.setParameter(key, parameters.get(key));
			}
		}
		transformer.transform(xmlSource, outputTarget);
		log.info("xslt tranformer processed.");
		return output;
	}
	
	/**
	 * @return the output
	 */
	public Resource getOutput() {
		return output;
	}
	
	/**
	 * @param output
	 *            the output to set
	 */
	public void setOutput(Resource output) {
		Assert.notNull(output, "output file could not be null");
		this.output = output;
	}
	
	/**
	 * @return the xsl
	 */
	public Resource getXsl() {
		return xsl;
	}
	
	/**
	 * @param xsl
	 *            the xsl to set
	 * @throws IOException
	 */
	public void setXsl(Resource xsl) throws IOException {
		Assert.notNull(xsl, "xsl style sheet file could not be null");
		Assert.isTrue(xsl.exists(), "xsl style sheet not found [" + xsl.getURL() + "]");
		this.xsl = xsl;
	}
	
	/**
	 * @return the parameters
	 */
	public Map<String, String> getParameters() {
		return parameters;
	}
	
	/**
	 * @param parameters
	 *            the parameters to set
	 */
	public void setParameters(Map<String, String> parameters) {
		this.parameters = parameters;
	}
	
}
